﻿using System;
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace DependencyAnalysis.DataModel
{
    [Serializable]
    [DataContract(IsReference = true)]
    [KnownType(typeof(SubmoduleDescriptor))]
    [KnownType(typeof(MemberDescriptor))]
    [KnownType(typeof(NodeVisibility))]
    [KnownType(typeof(AbstractionType))]
    public class TypeDescriptor : IDescriptor
    {
        private string _identifier;

        [DataMember(Order = 1)]
        public string Identifier
        {
            get { return _identifier; }
            set
            {
                _identifier = value;
                ComparableIdentifier = ("" + _identifier).ToLowerInvariant();
            }
        }

        [DataMember(Order = 2)]
        public string Name { get; set; }

        [DataMember(Order = 3)]
        public string FullName { get; set; }

        [DataMember(Order = 4)]
        public SubmoduleDescriptor Submodule { get; set; }

        [DataMember(Order = 5)]
        public NodeVisibility Visibility { get; set; }

        [DataMember(Order = 6)]
        public AbstractionType AbstractionType { get; set; }

        public IDescriptor Parent { get { return Submodule; } }

        [DataMember(Order = 9)]
        public IList<TypeDescriptor> ImplementingTypes { get; set; }

        [DataMember(Order = 10)]
        public IList<TypeDescriptor> InheritedTypes { get; set; }

        [NonSerialized]
        public Type Type;

        [DataMember(Order = 11)]
        private readonly IList<MemberDescriptor> _members = new List<MemberDescriptor>();

        public IList<MemberDescriptor> Members
        {
            get { return _members; }
        }

        [DataMember(Order = 12)]
        public bool IsGenerated { get; set; }

        [DataMember(Order = 13)]
        public bool IsDataObject { get; set; }

        [DataMember(Order = 14)]
        public bool IsEnum { get; set; }

        [DataMember(Order = 14)]
        public TypeDescriptor OriginatingType { get; set; }

        public override bool Equals(object obj)
        {
            if (!(obj is TypeDescriptor)) return false;

            return string.Equals(ComparableIdentifier, ((TypeDescriptor)obj).ComparableIdentifier);
        }

        internal string ComparableIdentifier { get; set; }

        public override int GetHashCode()
        {
            return ("" + ComparableIdentifier).GetHashCode();
        }

        public override string ToString()
        {
            return GetType().Name + ": " + FullName;
        }
    }
}
